package com.wft.design.common.security.service;

import com.wft.design.common.core.util.WebUtils;
import com.wft.design.common.security.bean.Authentication;
import com.wft.design.common.security.exception.AuthenticationException;
import com.wft.design.common.security.exception.UnauthorizedException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;

/**
 * @author WFT
 * @date 2019/12/30
 * description:
 */
@Service
@RequiredArgsConstructor
public class AuthenticationManager {

    private final static String ON_LINE_ACCOUNT = "on-line-account";

    private final TokenStorageService tokenStorageService;
    private final AccessTokenService accessTokenService;

    /**
     * 获取凭证信息
     * @return com.wft.design.common.security.bean.Authentication
     * @throws UnauthorizedException 401异常
     * @throws AuthenticationException 407异常
     */
    public Authentication getAuthentication() throws UnauthorizedException, AuthenticationException {
        //  尝试直接从request作用域中获取凭证信息
        HttpServletRequest request = WebUtils.getHttpServletRequest();
        Object onLineAccount = request.getAttribute(ON_LINE_ACCOUNT);
        if (null != onLineAccount){
            return (Authentication) onLineAccount;
        }
        Authentication authentication = this.getAuthentication(request);
        //  将获取到的凭证信息存放到request作用域中,方便下次使用
        request.setAttribute(ON_LINE_ACCOUNT,authentication);
        return authentication;
    }

    public void removeAuthentication(HttpServletRequest request) throws UnauthorizedException{
        //  获取accessToken
        String accessToken = this.tokenStorageService.getAccessToken(request);
        //  删除凭证信息
        this.accessTokenService.removeAccessToken(accessToken);
    }

    /**
     * 从请求中获取凭证信息
     * @param request 请求
     * @return com.wft.design.common.security.bean.Authentication
     * @throws UnauthorizedException 401异常
     * @throws AuthenticationException 407异常
     */
    private Authentication getAuthentication(HttpServletRequest request) throws UnauthorizedException, AuthenticationException{
        //  获取accessToken
        String accessToken = this.tokenStorageService.getAccessToken(request);
        //  获取凭证信息
        return this.accessTokenService.getAuthentication(accessToken);
    }
}
